package com.ruoyi.web.controller.project;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.project.domain.entity.ProjectFee;
import com.ruoyi.project.domain.entity.ProjectPromissory;
import com.ruoyi.project.domain.query.ProjectFeeQuery;
import com.ruoyi.project.domain.query.ProjectPromissoryQuery;
import com.ruoyi.project.service.IProjectFeeService;
import com.ruoyi.project.service.IProjectPromissoryService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

import static com.ruoyi.common.utils.PageUtils.startPage;

@RestController
@RequestMapping("/project/promissory")
public class ProjectPromissoryController {

    @Resource
    private IProjectPromissoryService projectPromissoryService;



    /**
     * 查询期票承兑信息列表 已作废的(删除的)
     */
    @GetMapping("/revokeList")
    public TableDataInfo revokeList(ProjectPromissoryQuery query) {
        Page<Object> page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ProjectPromissory> list = projectPromissoryService.getRevokeList(query);

        return new TableDataInfo(list, page.getTotal());
    }

    /**
     * 查询期票承兑信息列表
     */
    @GetMapping("/list")
    public TableDataInfo list(ProjectPromissoryQuery query) {
        Page<Object> page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        // 获取当前日期（只取年月日）
        QueryWrapper<ProjectPromissory> queryWrapper = new QueryWrapper<>();
        // 1. 添加查询条件（非空判断）
        if (query.getNoteType() != null) {
            queryWrapper.eq("note_type", query.getNoteType());
        }
        if (StringUtils.isNotBlank(query.getHousekeeperName())) {
            queryWrapper.like("housekeeper_name", query.getHousekeeperName());
        }
        if (StringUtils.isNotBlank(query.getDrawer())) {
            queryWrapper.like("drawer", query.getDrawer());
        }

        if (StringUtils.isNotBlank(query.getPayer())) {
            queryWrapper.like("payer", query.getPayer());
        }


        if (StringUtils.isNotBlank(query.getPayee())) {
            queryWrapper.like("payee", query.getPayee());
        }

        // 2. 添加过期记录的条件：只显示当月的过期记录
        LocalDate today = LocalDate.now();
        LocalDate firstDayOfMonth = today.withDayOfMonth(1);  // 当月第一天
        LocalDate nextMonthFirstDay = firstDayOfMonth.plusMonths(1);  // 下月第一天
        if ("2".equals(query.getOverDate())) {//查询已到期的
            queryWrapper.lt("end_date", today); // end_date < 当前日期即可
            queryWrapper.orderByDesc("end_date"); // 越近今天的排前面
        } else if ("3".equals(query.getOverDate())) {//查询未到期的
            queryWrapper.ge("end_date", today);
            queryWrapper.orderByAsc("end_date");
        }else {

            queryWrapper.and(wrapper ->
                    wrapper
                            // 未过期记录 (end_date >= today)
                            .ge("end_date", today)
                            .or()
                            // 过期记录：必须是当月的 (end_date < today 且 end_date >= 当月第一天 且 end_date < 下月第一天)
                            .lt("end_date", today)
                            .ge("end_date", firstDayOfMonth)
                            .lt("end_date", nextMonthFirstDay)
            );
            // 3. 自定义排序逻辑
            queryWrapper
                    // 先按 end_date >= 今天 降序（未过期排前面）
                    // 再按 end_date 升序（日期小的排前面）
                    .orderByAsc("end_date");
        }
        List<ProjectPromissory> list = projectPromissoryService.list(queryWrapper);
        // 获取当前日期的开始时间（00:00:00）
        Date todayStart = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());

        for (ProjectPromissory promissory : list) {
            Date endDate = promissory.getEndDate();
            String noteType = promissory.getNoteType();

            if (endDate != null && endDate.before(todayStart)) {
                // 已过期
                promissory.setStatus("1");
            } else if ("2".equals(noteType) || "4".equals(noteType)) {
                // 开票类（未过期）
                promissory.setStatus("2");
            } else if ("1".equals(noteType) || "3".equals(noteType) || "5".equals(noteType)) {
                // 收票类（未过期）
                promissory.setStatus("3");
            } else {
                // 其他未知类型，可选设为空或默认值
                promissory.setStatus("");
            }
        }

        return new TableDataInfo(list, page.getTotal());
    }



    /**
     * 查询期票承兑信息统计列表
     */
    @GetMapping("/getResult")
    public Map<String, Object> getResult(ProjectPromissoryQuery query) {
        Map<String, Object> map = new HashMap<>();

        // 初始化各类金额为 BigDecimal.ZERO
        BigDecimal outPromissory = BigDecimal.ZERO;  // 开据期票（noteType == "2"）
        BigDecimal outRedeem = BigDecimal.ZERO;      // 开据承兑（noteType == "4"）
        BigDecimal outTotal = BigDecimal.ZERO;       // 开据总额

        BigDecimal acceptPromissory = BigDecimal.ZERO; // 收到期票（noteType == "1"）
        BigDecimal acceptRedeem = BigDecimal.ZERO;     // 收到承兑（noteType == "3"）
        BigDecimal acceptTotal = BigDecimal.ZERO;      // 收到总额

        BigDecimal letter = BigDecimal.ZERO;//保函  加到收到总额里面

        // 获取当前日期的开始时间：00:00:00
        Date currentDate = Date.from(
                LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()
        );

        // 构造查询条件：endDate >= 当前日期 过期的是不进行统计的
        LambdaQueryWrapper<ProjectPromissory> queryWrapper = new LambdaQueryWrapper<>();
        // 1. 添加查询条件（非空判断）
        if (query.getNoteType() != null) {
            queryWrapper.eq(ProjectPromissory::getNoteType, query.getNoteType());
        }
        if (StringUtils.isNotBlank(query.getHousekeeperName())) {
            queryWrapper.like(ProjectPromissory::getHousekeeperName, query.getHousekeeperName());
        }
        if (StringUtils.isNotBlank(query.getDrawer())) {
            queryWrapper.like(ProjectPromissory::getDrawer, query.getDrawer());
        }

        if (StringUtils.isNotBlank(query.getPayer())) {
            queryWrapper.like(ProjectPromissory::getPayer, query.getPayer());
        }


        if (StringUtils.isNotBlank(query.getPayee())) {
            queryWrapper.like(ProjectPromissory::getPayee, query.getPayee());
        }

        if ("2".equals(query.getOverDate())) {
            //查询已到期的
            LocalDate today = LocalDate.now();
            queryWrapper.lt(ProjectPromissory::getEndDate, today); // end_date < 当前日期即可
        }else { //其他情况
            //只统计没到期的  日期大于等于今天的
            queryWrapper.ge(ProjectPromissory::getEndDate, currentDate);
        }

        // 查询数据
        List<ProjectPromissory> list = projectPromissoryService.list(queryWrapper);


        LambdaQueryWrapper<ProjectPromissory> monthQueryWrapper = new LambdaQueryWrapper<>();
        monthQueryWrapper.ge(ProjectPromissory::getEndDate, currentDate);
        List<ProjectPromissory> monthList = projectPromissoryService.list(monthQueryWrapper);


// 获取当前年月
        Calendar now = Calendar.getInstance();
        int currentYear = now.get(Calendar.YEAR);
        int currentMonth = now.get(Calendar.MONTH) + 1; // 月份从0开始，所以+1

//当前年份的当前月份的开据总额和收到总额
        BigDecimal currentMonthOut = BigDecimal.ZERO;
        BigDecimal currentMonthIn = BigDecimal.ZERO;

//当前年份的当前下一个月的开据总额和收到总额
        BigDecimal nextMonthOut = BigDecimal.ZERO;
        BigDecimal nextMonthIn = BigDecimal.ZERO;

//当前年份的当前下两个月的开据总额和收到总额 不包含一个月的
        BigDecimal nextTwoMonthOut = BigDecimal.ZERO;
        BigDecimal nextTwoMonthIn = BigDecimal.ZERO;

//当前年份的当前下三个月的开据总额和收到总额 不包含一个月的和两个月的
        BigDecimal nextThreeMonthOut = BigDecimal.ZERO;
        BigDecimal nextThreeMonthIn = BigDecimal.ZERO;

        for (ProjectPromissory promissory : monthList) {
            Date endDate = promissory.getEndDate();
            String noteType = promissory.getNoteType();
            BigDecimal amount = promissory.getMoney() != null ? promissory.getMoney() : BigDecimal.ZERO;

            if (endDate == null) {
                continue; // 如果结束日期为空，跳过处理
            }

            Calendar endCal = Calendar.getInstance();
            endCal.setTime(endDate);
            int endYear = endCal.get(Calendar.YEAR);
            int endMonth = endCal.get(Calendar.MONTH) + 1;

            // 只处理当前年份的票据
            if (endYear != currentYear) {
                continue;
            }

            int monthDiff = endMonth - currentMonth;

            if ("1".equals(noteType) || "3".equals(noteType) || "5".equals(noteType)) {
                // 加入到收到总额
                if (monthDiff == 0) {
                    currentMonthIn = currentMonthIn.add(amount);
                } else if (monthDiff == 1) {
                    nextMonthIn = nextMonthIn.add(amount);
                } else if (monthDiff == 2) {
                    nextTwoMonthIn = nextTwoMonthIn.add(amount);
                } else if (monthDiff == 3) {
                    nextThreeMonthIn = nextThreeMonthIn.add(amount);
                }
            } else if ("2".equals(noteType) || "4".equals(noteType)) {
                // 加入到开据总额
                if (monthDiff == 0) {
                    currentMonthOut = currentMonthOut.add(amount);
                } else if (monthDiff == 1) {
                    nextMonthOut = nextMonthOut.add(amount);
                } else if (monthDiff == 2) {
                    nextTwoMonthOut = nextTwoMonthOut.add(amount);
                } else if (monthDiff == 3) {
                    nextThreeMonthOut = nextThreeMonthOut.add(amount);
                }
            }
        }

        map.put("currentMonthIn", currentMonthIn);
        map.put("nextMonthIn", nextMonthIn);
        map.put("nextTwoMonthIn", nextTwoMonthIn);
        map.put("nextThreeMonthIn", nextThreeMonthIn);
        map.put("currentMonthOut", currentMonthOut);
        map.put("nextMonthOut", nextMonthOut);
        map.put("nextTwoMonthOut", nextTwoMonthOut);
        map.put("nextThreeMonthOut", nextThreeMonthOut);



        // 遍历列表，按 noteType 分类统计金额
        for (ProjectPromissory promissory : list) {
            String noteType = promissory.getNoteType();
            BigDecimal amount = promissory.getMoney() != null?promissory.getMoney():BigDecimal.ZERO;  // 假设金额字段是 BigDecimal 类型的 getAmount()

            if ("1".equals(noteType)) {
                acceptPromissory = acceptPromissory.add(amount);
            } else if ("2".equals(noteType)) {
                outPromissory = outPromissory.add(amount);
            } else if ("3".equals(noteType)) {
                acceptRedeem = acceptRedeem.add(amount);
            } else if ("4".equals(noteType)) {
                outRedeem = outRedeem.add(amount);
            }else if ("5".equals(noteType)) {
                letter = letter.add(amount);
            }
        }
        // 计算总额
        acceptTotal = acceptPromissory.add(acceptRedeem);
        acceptTotal = acceptTotal.add(letter);
        outTotal = outPromissory.add(outRedeem);

        // 放入 map 返回
        map.put("acceptPromissory", acceptPromissory);   // 收到期票
        map.put("acceptRedeem", acceptRedeem);           // 收到承兑
        map.put("acceptTotal", acceptTotal);             // 收到总额
        map.put("outPromissory", outPromissory);         // 开据期票
        map.put("outRedeem", outRedeem);                 // 开据承兑
        map.put("outTotal", outTotal);                   // 开据总额

        return map;
    }

    /**
     * 查询期票承兑信息统计列表
     */
    @GetMapping("/listData")
    public Map<String,Object> listPromissoryData(ProjectPromissoryQuery query){
        Map<String,Object> map = new HashMap<>();
        BigDecimal total = BigDecimal.ZERO;
        LambdaQueryWrapper<ProjectPromissory> queryWrapper = new LambdaQueryWrapper<>();

        //判断 如果是收到期票+承兑 或  开据期票+承兑

        if ("5".equals(query.getNoteType())) {
            // 收到期票 + 承兑：包含 note_type = '1' 或 '3'
            queryWrapper.and(wrapper -> wrapper
                    .eq(ProjectPromissory::getNoteType, "1")
                    .or()
                    .eq(ProjectPromissory::getNoteType, "3"));
        } else if ("6".equals(query.getNoteType())) {
            // 开具期票 + 承兑：包含 note_type = '2' 或 '4'
            queryWrapper.and(wrapper -> wrapper
                    .eq(ProjectPromissory::getNoteType, "2")
                    .or()
                    .eq(ProjectPromissory::getNoteType, "4"));
        } else {
            // 其他情况：直接按传入的 noteType 精确查询
            queryWrapper.eq(StringUtils.isNotEmpty(query.getNoteType()), ProjectPromissory::getNoteType, query.getNoteType());
        }


        // 模糊查询 companyName，在 Payee 或 Payer 中任一匹配
        if (StringUtils.isNotEmpty(query.getCompanyName())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(ProjectPromissory::getPayee, query.getCompanyName())
                    .or()
                    .like(ProjectPromissory::getPayer, query.getCompanyName()));
        }
        // 获取时间范围并构建 endDate 查询条件
        LocalDate beginAcceptTime = query.getBeginAcceptTime();
        LocalDate endAcceptTime = query.getEndAcceptTime();
        if (beginAcceptTime != null && endAcceptTime != null) {
            Date beginDate = Date.from(beginAcceptTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endDateBound = Date.from(endAcceptTime.atStartOfDay(ZoneId.systemDefault()).plusDays(1).minusSeconds(1).toInstant());
            queryWrapper.between(ProjectPromissory::getEndDate, beginDate, endDateBound);
        }
        queryWrapper.orderByAsc(ProjectPromissory::getEndDate);
        List<ProjectPromissory> list = projectPromissoryService.list(queryWrapper);
        for (ProjectPromissory projectPromissory : list) {
            total = total.add(projectPromissory.getMoney());
        }
        map.put("data", list);
        map.put("total", total);
        return map;
    }



    /**
     * 导出期票承兑信息列表
     */
    @Log(title = "期票承兑信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ProjectPromissory projectPromissory)
    {
        List<ProjectPromissory> list = projectPromissoryService.list();
        ExcelUtil<ProjectPromissory> util = new ExcelUtil<ProjectPromissory>(ProjectPromissory.class);
        util.exportExcel(response, list, "期票承兑信息数据");
    }

    /**
     * 获取期票承兑信息详细信息
     */
    @GetMapping(value = "/{id}")
    public R getInfo(@PathVariable("id") Long id)
    {
        return R.ok(projectPromissoryService.getById(id));
    }

    /**
     * 新增期票承兑信息
     */
    @Log(title = "期票承兑信息", businessType = BusinessType.INSERT)
    @PostMapping
    public R add(@RequestBody ProjectPromissory projectPromissory)
    {
        Long userId = SecurityUtils.getUserId();
        String nickName = SecurityUtils.getLoginUser().getUser().getNickName();
        projectPromissory.setDrawerId(userId);
        projectPromissory.setDrawer(nickName);
        return R.ok(projectPromissoryService.save(projectPromissory));
    }

    /**
     * 修改期票承兑信息
     */
    @Log(title = "期票承兑信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public R edit(@RequestBody ProjectPromissory projectPromissory)
    {
        Long userId = SecurityUtils.getUserId();
        String nickName = SecurityUtils.getLoginUser().getUser().getNickName();
        projectPromissory.setDrawerId(userId);
        projectPromissory.setDrawer(nickName);
        return R.ok(projectPromissoryService.updateById(projectPromissory));
    }

    /**
     * 删除期票承兑信息
     */
    @Log(title = "期票承兑信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{id}")
    public R remove(@PathVariable Long id)
    {
        boolean b = projectPromissoryService.removeById(id);
        if (b){
            //添加日志记录

        }
        return R.ok(b);
    }


}
